package com.socket.netty;

import com.socket.batch.collector.DataAnalysis;
import com.socket.batch.collector.MessageCollector;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.ReferenceCountUtil;
import org.apache.log4j.Logger;

//自定义的ChannelHandler
public class DateServerHandler extends ChannelInboundHandlerAdapter {
    private static final transient Logger log = Logger.getLogger(DateServerHandler.class);
    private int count=0;

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception
    {
        System.out.println("---------------channelActive 客户端连上了...");
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("---------------channelRead 服务端接收到消息了...");
        ByteBuf buf=(ByteBuf) msg;
        byte[] req = new byte[buf.readableBytes()];
        buf.readBytes(req);

        String body = DataAnalysis.byte2hex(req);

        body += "5D";//添加分隔符
        //System.out.println("---------------接收到的消息为:"+body);

        //System.out.println("---------------接收到的消息长度为:"+DataAnalysis.hex2Bytes(body).length);

        body = body.replace("5A01", "5B");
        body = body.replace("5A02", "5A");
        body = body.replace("5E01", "5D");
        body = body.replace("5E02", "5E");
        String msgId = body.substring(18, 22);
        System.out.println("msgId:"+msgId);
        if(("1001").equals(msgId)){
            try {
                body = body.replace(body.substring(138,144), "").substring(2);
                byte[] bytes = DataAnalysis.hex2Bytes(body);
                //System.out.println("待校验的hex串:"+body);
                String s1 = "0000001F"+"00000000"+"100200BC614E0100010000000000"+"00"+"00000000";
                String s = "5B" + s1 +Integer.toHexString(getCRC(DataAnalysis.hex2Bytes(s1))).toUpperCase()+"5D";
                //System.out.println("CRC Code:"+Integer.toHexString(getCRC(DataAnalysis.hex2Bytes(s1))).toUpperCase());
                //System.out.println("返回给客户端的hex为:"+s);
                byte[] b = DataAnalysis.hex2Bytes(s);
                //System.out.println("b.length=" + b.length);
                //ByteBuf buffer = ctx.alloc().buffer(4 * b.length);
                ByteBuf buffer = PooledByteBufAllocator.DEFAULT.heapBuffer(4 * b.length);
                assert buf.refCnt() == 1;

                //传递给ChannelOutboundHandler
                ctx.writeAndFlush(buffer.writeBytes(b));
                //System.out.println("返回给客户端的数据是:"+DataAnalysis.byte2hex(s.getBytes()));

            } finally {
                ReferenceCountUtil.release(msg); // (2)

            }
        }else if (("1005").equals(msgId)){
            try {
                body = body.replace(body.substring(46,52), "").substring(2);
                byte[] bytes = DataAnalysis.hex2Bytes(body);
                //System.out.println("待校验的hex串:"+body);
                String s1 = "0000001A00000000100600BC614E0100010000000000";
                String s = "5B" + s1 +Integer.toHexString(getCRC(DataAnalysis.hex2Bytes(s1))).toUpperCase()+"5D";
                //System.out.println("CRC Code:"+Integer.toHexString(getCRC(DataAnalysis.hex2Bytes(s1))).toUpperCase());
                //System.out.println("返回给客户端的hex为:"+s);
                byte[] b = DataAnalysis.hex2Bytes(s);
                //System.out.println("b.length=" + b.length);
                //ByteBuf buffer = ctx.alloc().buffer(4 * b.length);
                ByteBuf buffer = PooledByteBufAllocator.DEFAULT.heapBuffer(4 * b.length);
                ctx.writeAndFlush(buffer.writeBytes(b));
                //System.out.println("返回给客户端的数据是:"+DataAnalysis.byte2hex(s.getBytes()));
            } finally {
                ReferenceCountUtil.release(msg); // (2)
            }
        }
        else if (("1200").equals(msgId)){
            try {
                String dataType = body.substring(90, 94);
                System.out.println(dataType);
                if(("1202").equals(dataType)){
                    MessageCollector.collect(DataAnalysis.hex2Bytes(body));
                }
                if(("1203").equals(dataType)){
                    MessageCollector.collect(DataAnalysis.hex2Bytes(body));
                }
            } finally {
                ReferenceCountUtil.release(msg); // (2)
            }

        }



    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception
    {
        //ctx.flush();
        // 第一种方法：写一个空的buf，并刷新写出区域。完成后关闭sock channel连接。
        //ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception
    {
        System.out.println("---------------exceptionCaught 网络异常，关闭网络");
        cause.printStackTrace();
        ctx.close();
    }

    public static int getCRC(byte[] bytes){
        int crc = 0xFFFF;          // initial value
        int polynomial = 0x1021;
        for (int index = 0 ; index< bytes.length; index++) {
            byte b = bytes[index];
            for (int i = 0; i < 8; i++) {
                boolean bit = ((b   >> (7-i) & 1) == 1);
                boolean c15 = ((crc >> 15    & 1) == 1);
                crc <<= 1;
                if (c15 ^ bit) crc ^= polynomial;
            }
        }
        crc &= 0xffff;
        return crc;

//        int crc = 0xFFFF;          // initial value
//        int polynomial = 0x1021;   // 0001 0000 0010 0001  (0, 5, 12)
//
//        for (byte b : bytes) {
//            for (int i = 0; i < 8; i++) {
//                boolean bit = ((b   >> (7-i) & 1) == 1);
//                boolean c15 = ((crc >> 15    & 1) == 1);
//                crc <<= 1;
//                if (c15 ^ bit) crc ^= polynomial;
//            }
//        }
//
//        crc &= 0xffff;
//        System.out.println("CRC16-CCITT = " + Integer.toHexString(crc));
//        return crc;

//        int crc_reg =0xFFFF;
//        short current;
//        for (int i = 0; i < bytes.length; i++)
//        {
//            current = (short)(bytes[i] << 8);
//            for (int j = 0; j < 8; j++)
//            {
//                if ((short)(crc_reg ^ current) < 0)
//                    crc_reg = (short)((crc_reg << 1) ^ 0x1021);
//                else
//                    crc_reg <<= 1;
//                current <<= 1;
//            }
//        }
//        return crc_reg;
    }

    public static void main(String[] args) {
        //String s = "5B000000480000000010010007C93201000000000000000007C93238363132383733313232312E31302E32322E313730000000000000000000000000000000000000001F99E7C55D";
//        String s = "5B0000001F0000125E100100BC614E0100010000000000EC715D";
//
//        System.out.println("s:"+ s.length());
//        byte[] b = DataAnalysis.hex2Bytes(s);
//        System.out.println("b length = [" + b.length + "]");


//        String string = "5B0000004800000C90100100BC614E010001000000000000BC614E31323334353637383132372E302E302E3100000000000000000000000000000000000000000000002708D4475D";
////        String string = "5B0000001F03A4852A1002000023030100000000000000000EFF4EAB5D";
//        System.out.println(string.length());
//        System.out.println(string.replace(string.substring(138,144), "").substring(2));
//        System.out.println(getCRC(DataAnalysis.hex2Bytes(string.replace(string.substring(138,144), "").substring(2))));
//        System.out.println(Integer.toHexString(getCRC(DataAnalysis.hex2Bytes(string.replace(string.substring(138,144), "").substring(2)))).toUpperCase());

//        String string = "0000001F00000000100200BC614E01000100000000000000000000";
//        //String string = "5B0000001F03A4852A1002000023030100000000000000000EFF4EAB5D";
//        String s = "5B0000001F"+"00000000"+"100200BC614E0100010000000000"+"00"+"00000000"+Integer.toHexString(getCRC(DataAnalysis.hex2Bytes(string))).toUpperCase()+"5D";
//        System.out.println(s);
//        System.out.println(getCRC(DataAnalysis.hex2Bytes(string)));
//        System.out.println(Integer.toHexString(getCRC(DataAnalysis.hex2Bytes(string))));
        String s1 = "0000001F"+"00000000"+"100200BC614E0100010000000000"+"00"+"00000000";
        String s = s1 +Integer.toHexString(getCRC(DataAnalysis.hex2Bytes(s1))).toUpperCase()+"5D";
        System.out.println("CRC Code:"+Integer.toHexString(getCRC(DataAnalysis.hex2Bytes(s1))).toUpperCase());
        System.out.println("返回给客户端的hex为:"+s);
    }
}